#include <commands\server\s_send_terrain_tile.h>
#include <commands\client\c_accept_terrain_tile.h>
#include <app\states\terrainTileState.h>

REGISTER_COMMAND(SERVER_SEND_TERRAIN_TILE, s_send_terrain_tile)

s_send_terrain_tile::s_send_terrain_tile() : command(0, NULL) {
  x = 0;
  y = 0;
  level = 0;
  data = NULL;
  size = 0;
}

s_send_terrain_tile::s_send_terrain_tile(unsigned int _type_id, streamingConnection *_connection) : command(_type_id, _connection) {
  x = 0;
  y = 0;
  level = 0;
  data = NULL;
  size = 0;
}

void 
s_send_terrain_tile::setData(int x_, int y_, int level_, unsigned char *data_, int size_) {
  x = x_;
  y = y_;
  level = level_;
  data = data_;
  size = size_;
}

unsigned char *
s_send_terrain_tile::getData(int &x_, int &y_, int &level_, int &size_) {
 x_ = x;
 y_ = y;
 level_ = level;
 size_ = size;

 return data;
}

void 
s_send_terrain_tile::decode(stringstream &bytes_stream, int data_size) {
#ifdef CLIENT

  #ifdef DEBUG_INFO
  std::cerr << "CLIENT DECODE: s_send_terrain_tile" << std::endl;
  #endif

  bytes_stream >> x;
  bytes_stream >> y;
  bytes_stream >> level;
  bytes_stream >> size;

  data = new unsigned char[size];
  bytes_stream.read((char *) data, size);

  streamingConnection *conn = getconnection();
  terrainTileState *ttstate = GET_STATE(terrainTileState, conn);

  ttstate->receivedTerrainTile(x, y, level, data, size);

  delete data;

  c_accept_terrain_tile *cmd = (c_accept_terrain_tile *) commandFactory::instance().createCommand(CLIENT_ACCEPT_TERRAIN_TILE, getconnection());
  cmd->execute();
  delete cmd;

  ttstate->setState(nTerrainTile::READY);

#endif
}

void 
s_send_terrain_tile::execute() {
#ifdef SERVER
  
  #ifdef DEBUG_INFO
  std::cerr << "SERVER EXECUTE: s_send_terrain_tile" << std::endl;
  #endif

  unsigned int *id = new unsigned int[1];
  unsigned int *total_size = new unsigned int[1];
  unsigned int data_size;

  total_size[0] = sizeof(unsigned int); // total size itself

  id[0] = getTypeId();
  total_size[0] += sizeof(unsigned int); // id size

  stringstream bytes(ios::out | ios::in | ios::binary);
   bytes << x << endl;
   bytes << y << endl;
   bytes << level << endl;
   bytes << size;
   if (size != 0) {
     bytes.write((const char *) data, size);
   }
   bytes.seekg(0, ios::end);
  data_size = bytes.tellg();
  unsigned char *streamed_data = new unsigned char[data_size];
  bytes.seekg(0, ios::beg);
  bytes.read((char *) streamed_data, data_size);

  total_size[0] += data_size;

  sendBytes(total_size, sizeof(unsigned int));
  sendBytes(id, sizeof(unsigned int));

  sendBytes(streamed_data, data_size);

#endif
}

